﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Medianamik.Core.Security;
using DALS = Medianamik.Core.DAL.SubSonicDAL;
using Medianamik.Core.DAL.SubSonicDAL;
using Medianamik.Core.Sugar;
using SubSonic;
using Medianamik.Core.Interfaces;
using System.Data;
using System.Web.Security;
using Group = Medianamik.Core.Security.Group;

namespace Medianamik.Core.DAL
{
    internal class SubsonicSecurityDALProvider : ISecurityDALProvider
    {
        #region ISecurityDALProvider Members

        #region Type

        public IEnumerable<Permission> GetAllNodeTypePermissions()
        {
            DALS.TypePermissionCollection permissions = new DALS.TypePermissionCollection();
            permissions.Load();

            return permissions.Select(p => FromDALNodeTypePermission(p));
        }

        public IEnumerable<InheritedPermission> GetAllNodeTypeInheritedPermissions()
        {
            DALS.InheritedTypePermissionCollection permissions = new DALS.InheritedTypePermissionCollection();
            permissions.Load();

            return permissions.Select(p => FromDALInheritedNodeTypePermission(p));
        }

        public void TransacApplyPermissionsToType(Guid typeId, IEnumerable<Guid> overriddenGroups,
            IEnumerable<Permission> deletedPermissions, IEnumerable<Permission> updatedPermission,
            IEnumerable<Permission> newPermissions)
        {
            QueryCommandCollection commands = new QueryCommandCollection();

            commands.AddRange(newPermissions.Select(p =>
                ToDALTypePermission(p, true).GetInsertCommand("")));

            commands.AddRange(updatedPermission.Select(p =>
                ToDALTypePermission(p, false).GetUpdateCommand("")));

            commands.AddRange(deletedPermissions.Select(p =>
                new DeleteQuery(DALS.TypePermission.Schema)
                .WHERE(DALS.TypePermission.Columns.GroupId, p.GroupId)
                .AddWhere(DALS.TypePermission.Columns.TypeId, p.SecuredObjectId)
                .BuildCommand()));

            if (overriddenGroups.Count() > 0)
            {
                commands.Add(SPs.ApplyTypePermissionToChildren(typeId,
                    overriddenGroups.ToString(",")).Command);
            }

            DataService.ExecuteTransaction(commands);
        }

        #endregion

        #region Node

        public void TransacApplyPermissionsToNode(Guid nodeId, IEnumerable<Guid> overriddenGroups,
            IEnumerable<Permission> deletedPermissions, IEnumerable<Permission> updatedPermission,
            IEnumerable<Permission> newPermissions)
        {
            QueryCommandCollection commands = new QueryCommandCollection();

            commands.AddRange(newPermissions.Select(p =>
                ToDALNodePermission(p, true).GetInsertCommand("")));

            commands.AddRange(updatedPermission.Select(p =>
                ToDALNodePermission(p, false).GetUpdateCommand("")));

            commands.AddRange(deletedPermissions.Select(p =>
                new DeleteQuery(DALS.NodePermission.Schema)
                .WHERE(DALS.NodePermission.Columns.GroupId, p.GroupId)
                .AddWhere(DALS.NodePermission.Columns.NodeId, p.SecuredObjectId)
                .BuildCommand()));

            if (overriddenGroups.Count() > 0)
            {
                commands.Add(SPs.ApplyNodePermissionToChildren(nodeId,
                    overriddenGroups.ToString(",")).Command);
            }

            DataService.ExecuteTransaction(commands);
        }

        public IEnumerable<Permission> GetAllNodePermissions()
        {
            DALS.NodePermissionCollection permissions = new DALS.NodePermissionCollection();
            permissions.Load();

            return permissions.Select(p => FromDALNodePermission(p));
        }

        public IEnumerable<InheritedPermission> GetAllNodeInheritedPermissions()
        {
            DALS.InheritedNodePermissionCollection permissions = new DALS.InheritedNodePermissionCollection();
            permissions.Load();

            return permissions.Select(p => FromDALInheritedNodePermission(p));
        }

        #endregion

        public IEnumerable<Approbation> GetAllNodeApprobations()
        {
            var approbations = new NodeApprobationCollection();
            approbations.Load();

            return approbations.Select(p => FromDALNodeApprobation(p));
        }

        public void AddNodeApprobation(Approbation approbation)
        {
            QueryCommand command = ToDALNodeApprobation(approbation, true).GetInsertCommand("");

            DataService.ExecuteQuery(command);
        }

        public void UpdateNodeApprobation(Approbation approbation)
        {
            QueryCommand command = ToDALNodeApprobation(approbation, false).GetUpdateCommand("");

            DataService.ExecuteQuery(command);
        }

        public void DeleteNodeApprobation(Guid nodeId)
        {

            QueryCommand command =
                new DeleteQuery(NodeApprobation.Schema)
                    .WHERE(NodeApprobation.Columns.NodeId, nodeId)
                    .BuildCommand();
            DataService.ExecuteQuery(command);
        }

        #region Roles, Groups

        public IEnumerable<Guid> GetUsersInGroups(IEnumerable<String> groups)
        {
            var col = new UserNameInGroupNameCollection();
            col.Where(UserNameInGroupName.Columns.GroupName, 
                Comparison.In, groups.Distinct(StringComparer.OrdinalIgnoreCase));
            col.OrderByAsc(UserNameInGroupName.Columns.GroupName)
                .OrderByAsc(UserNameInGroupName.Columns.UserName);
            col.Load();
            return col.Select(data => data.GetColumnValue<Guid>(UserNameInGroupName.Columns.UserId));
        }

        public IEnumerable<IRole> GetRoles()
        {
            return new DALS.RoleCollection().Load().Cast<IRole>();
        }

        public IEnumerable<Group> GetGroups()
        {
            return new DALS.GroupCollection().Load().Select(g => FromDALGroup(g));
        }

        public IEnumerable<IUserInGroup> GetUsersInGroups()
        {
            return new DALS.UserNameInGroupNameCollection()
            .Load().Cast<IUserInGroup>();
        }
        public IEnumerable<IRoleInGroup> GetRolesInGroups()
        {
            return new DALS.RoleNameInGroupNameCollection()
            .Load().Cast<IRoleInGroup>();
        }

        public void AddUsersToGroups(string[] pUsers, string[] pGroups)
        {
            if (pUsers.Length < 1 || pGroups.Length < 1)
            {
                return;
            }

            var userQuery = DALS.User.Query();
            userQuery.IN(DALS.User.Columns.Name, pUsers.Cast<object>().ToArray());
            var users = new DALS.UserCollection();
            using (IDataReader reader = userQuery.ExecuteReader())
            {
                users.Load(reader);
            }

            var groupQuery = DALS.Group.Query();
            groupQuery.IN(DALS.Group.Columns.Name, pGroups.Cast<object>().ToArray());
            var groups = new DALS.GroupCollection();
            using (IDataReader reader = groupQuery.ExecuteReader())
            {
                groups.Load(reader);
            }

            if (users.Count < 1 || groups.Count < 1) { return; }

            foreach (var user in users)
            {
                //Supprimer les relations existantes
                var usersInGroupsDeleteQuery = DALS.UserInGroup.Query();
                usersInGroupsDeleteQuery.QueryType = QueryType.Delete;
                usersInGroupsDeleteQuery.WHERE(DALS.UserInGroup.Columns.UserId, user.UserId.ToString());
                usersInGroupsDeleteQuery.IN(DALS.UserInGroup.Columns.GroupId, groups.Select(g => (object)g.GroupId.ToString()).ToArray());
                usersInGroupsDeleteQuery.Execute();
            }


            var usersInGroupsCol = new DALS.UserInGroupCollection();

            foreach (var user in users)
            {
                foreach (var group in groups)
                {
                    var userInGroup = new UserInGroup();
                    userInGroup.UserId = user.UserId;
                    userInGroup.GroupId = group.GroupId;
                    usersInGroupsCol.Add(userInGroup);
                }
            }
            usersInGroupsCol.SaveAll();
            RoleCacheManager.Instance.Clear();
        }
        public void AddRolesToGroups(string[] pRoles, string[] pGroups)
        {
            if (pRoles.Length < 1 || pGroups.Length < 1)
            {
                return;
            }

            var roleQuery = DALS.Role.Query();
            roleQuery.IN(DALS.Role.Columns.Name, pRoles.Cast<object>().ToArray());
            var roles = new DALS.RoleCollection();
            using (IDataReader reader = roleQuery.ExecuteReader())
            {
                roles.Load(reader);
            }

            var groupQuery = DALS.Group.Query();
            groupQuery.IN(DALS.Group.Columns.Name, pGroups.Cast<object>().ToArray());
            var groups = new DALS.GroupCollection();
            using (IDataReader reader = groupQuery.ExecuteReader())
            {
                groups.Load(reader);
            }

            if (roles.Count < 1 || groups.Count < 1) { return; }

            foreach (var role in roles)
            {
                var rolesInGroupsDeleteQuery = DALS.RoleInGroup.Query();
                rolesInGroupsDeleteQuery.QueryType = QueryType.Delete;
                rolesInGroupsDeleteQuery.WHERE(DALS.RoleInGroup.Columns.RoleId, role.RoleId.ToString());
                rolesInGroupsDeleteQuery.IN(DALS.RoleInGroup.Columns.GroupId, groups.Select(g => (object)g.GroupId.ToString()).ToArray());
                rolesInGroupsDeleteQuery.Execute();
            }


            var rolesInGroupsCol = new DALS.RoleInGroupCollection();

            foreach (var role in roles)
            {
                foreach (var group in groups)
                {
                    var roleInGroup = new RoleInGroup();
                    roleInGroup.RoleId = role.RoleId;
                    roleInGroup.GroupId = group.GroupId;
                    rolesInGroupsCol.Add(roleInGroup);
                }
            }
            rolesInGroupsCol.SaveAll();
        }

        public void RemoveUsersFromGroups(string[] pUsers, string[] pGroups)
        {
            if (pUsers.Length < 1 && pGroups.Length < 1)
            {
                return;
            }

            var userQuery = DALS.User.Query();
            userQuery.IN(DALS.User.Columns.Name, pUsers.Cast<object>().ToArray());
            var users = new DALS.UserCollection();
            using (IDataReader reader = userQuery.ExecuteReader())
            {
                users.Load(reader);
            }

            var groupQuery = DALS.Group.Query();
            groupQuery.IN(DALS.Group.Columns.Name, pGroups.Cast<object>().ToArray());
            var groups = new DALS.GroupCollection();
            using (IDataReader reader = groupQuery.ExecuteReader())
            {
                groups.Load(reader);
            }

            if (users.Count < 1 || groups.Count < 1) { return; }

            //Supprimer les relations existantes
            foreach (var user in users)
            {
                var usersInGroupsDeleteQuery = DALS.UserInGroup.Query();
                usersInGroupsDeleteQuery.QueryType = QueryType.Delete;
                usersInGroupsDeleteQuery.WHERE(DALS.UserInGroup.Columns.UserId, user.UserId.ToString());
                usersInGroupsDeleteQuery.IN(DALS.UserInGroup.Columns.GroupId, groups.Select(g => (object)g.GroupId.ToString()).ToArray());
                usersInGroupsDeleteQuery.Execute();
            }

        }
        public void RemoveRolesFromGroups(string[] pRoles, string[] pGroups)
        {
            if (pRoles.Length < 1 && pGroups.Length < 1)
            {
                return;
            }

            var roleQuery = DALS.Role.Query();
            roleQuery.IN(DALS.Role.Columns.Name, pRoles.Cast<object>().ToArray());
            var roles = new DALS.RoleCollection();
            using (IDataReader reader = roleQuery.ExecuteReader())
            {
                roles.Load(reader);
            }

            var groupQuery = DALS.Group.Query();
            groupQuery.IN(DALS.Group.Columns.Name, pGroups.Cast<object>().ToArray());
            var groups = new DALS.GroupCollection();
            using (IDataReader reader = groupQuery.ExecuteReader())
            {
                groups.Load(reader);
            }

            if (roles.Count < 1 || groups.Count < 1) { return; }

            foreach (var role in roles)
            {
                var rolesInGroupsDeleteQuery = DALS.RoleInGroup.Query();
                rolesInGroupsDeleteQuery.QueryType = QueryType.Delete;
                rolesInGroupsDeleteQuery.WHERE(DALS.RoleInGroup.Columns.RoleId, role.RoleId.ToString());
                rolesInGroupsDeleteQuery.IN(DALS.RoleInGroup.Columns.GroupId, groups.Select(g => (object)g.GroupId.ToString()).ToArray());
                rolesInGroupsDeleteQuery.Execute();
            }

        }

        public void CreateRole(string pRoleName)
        {
            var role = new DALS.Role();
            role.RoleId = Guid.NewGuid();
            role.Name = pRoleName;
            role.Save();
        }
        public void CreateGroup(string pGroupName, Guid parentGroupId)
        {
            var group = new DALS.Group();
            group.GroupId = Guid.NewGuid();
            group.Name = pGroupName;
            group.ParentGroupId = parentGroupId;
            group.Save();
        }

        public void DeleteRole(string pRoleName)
        {
            Query q = DALS.Role.Query();
            q.QueryType = QueryType.Delete;
            q.WHERE(DALS.Role.Columns.Name, pRoleName);
            q.Execute();
        }

        public void DeleteGroup(string pGroupName)
        {
            Query q = DALS.Group.Query();
            q.QueryType = QueryType.Delete;
            q.WHERE(DALS.Group.Columns.Name, pGroupName);
            q.Execute();

        }

        #endregion

        #region Users

        public IUser[] GetUsers(int pageIndex, int pageSize, out int totalRecords)
        {
            Query countQuery = User.Query();
            totalRecords = countQuery.GetRecordCount();


            Query q = User.Query();
            q.PageIndex = pageIndex;
            q.PageSize = pageSize;
            UserCollection users = new UserCollection();
            using (IDataReader reader = q.ExecuteReader())
            {
                users.Load(reader);
            }

            return users.ToArray();

        }

        public IUser[] GetUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            Query countQuery = User.Query();
            countQuery.WHERE(User.Columns.Name, Comparison.Like, usernameToMatch);
            totalRecords = countQuery.GetRecordCount();

            Query q = User.Query();
            q.WHERE(User.Columns.Name, Comparison.Like, '%' + usernameToMatch + '%');
            q.PageIndex = pageIndex;
            q.PageSize = pageSize;
            UserCollection users = new UserCollection();
            using (IDataReader reader = q.ExecuteReader())
            {
                users.Load(reader);
            }

            return users.ToArray();

        }

        public IUser CreateUser(string username, string password, MembershipPasswordFormat pPasswordFormat, string salt, string email, string passwordQuestion, string passwordAnswer, bool isApproved, Guid providerUserKey)
        {
            User newUser = new User();
            newUser.Name = username;
            newUser.Password = password;
            newUser.Email = email;
            newUser.PasswordQuestion = passwordQuestion;
            newUser.PasswordAnswer = passwordAnswer;
            newUser.IsApproved = isApproved;
            newUser.UserId = providerUserKey;
            newUser.PasswordFormat = (int)pPasswordFormat;
            newUser.Salt = salt;

            newUser.Save(Utility.GetCurrentUserName());
            return newUser;

        }

        public void UpdateUser(string email, string comment, bool isApproved, bool isLockedOut, Guid providerUserKey)
        {
            User newUser = new User(providerUserKey);
            if (newUser.IsNew) { return; }

            newUser.Email = email;
            newUser.Comment = comment;
            newUser.IsApproved = isApproved;
            newUser.IsLockedOut = isLockedOut;

            newUser.Save();
        }

        public void DeleteUser(string username)
        {
            Query q = User.Query();
            q.QueryType = QueryType.Delete;
            q.WHERE(User.Columns.Name, username);
            q.Execute();
        }
        public void DeleteUser(Guid userId)
        {
            Query q = User.Query();
            q.QueryType = QueryType.Delete;
            q.WHERE(User.Columns.UserId, userId);
            q.Execute();
        }

        public void LockUser(string username)
        {
            User newUser = new User(User.Columns.Name, username);
            if (newUser.IsNew) { return; }

            newUser.IsLockedOut = true;
            newUser.LastLockedOutDate = DateTime.Now;

            newUser.Save();
        }

        public void SetLockUser(Guid userId, bool  locked)
        {
            var newUser = new User(User.Columns.UserId, userId);
            if (newUser.IsNew) { return; }

            newUser.IsLockedOut = locked;
            newUser.LastLockedOutDate = DateTime.Now;

            newUser.Save();
        }

        public void UnlockUser(string username)
        {
            User newUser = new User(User.Columns.Name, username);
            if (newUser.IsNew) { return; }

            newUser.IsLockedOut = false;
            newUser.Save();
        }

        public IUser GetUser(string username)
        {
            User user = new User(User.Columns.Name, username);
            if (user.IsNew) { return null; }

            return user;
        }

        public IUser GetUser(Guid providerUserKey)
        {
            User user = new User(providerUserKey);
            if (user.IsNew) { return null; }

            return user;
        }

        public void SetUserLastActivityDate(Guid providerUserKey, DateTime lastActivityDate)
        {
            Query q = User.Query();
            q.QueryType = QueryType.Update;
            q.WHERE(User.Columns.UserId, providerUserKey);
            q.AddUpdateSetting(User.Columns.LastActivityDate, lastActivityDate);
            q.Execute();
        }
        public void SetUserPassword(Guid providerUserKey, string password, MembershipPasswordFormat pPasswordFormat, string salt)
        {
            Query q = User.Query();
            q.QueryType = QueryType.Update;
            q.WHERE(User.Columns.UserId, providerUserKey);
            q.AddUpdateSetting(User.Columns.Password, password);
            q.AddUpdateSetting(User.Columns.PasswordFormat, pPasswordFormat);
            q.AddUpdateSetting(User.Columns.Salt, salt);
            q.Execute();
        }

        public void SetUserPasswordQuestionAndAnswer(Guid providerUserKey, string passwordQuestion, string passwordAnswer)
        {
            Query q = User.Query();
            q.QueryType = QueryType.Update;
            q.WHERE(User.Columns.UserId, providerUserKey);
            q.AddUpdateSetting(User.Columns.PasswordQuestion, passwordQuestion);
            q.AddUpdateSetting(User.Columns.PasswordAnswer, passwordAnswer);
            q.Execute();
        }


        #endregion

        #region Pages

        public IRole[] GetRolesForPage(Guid pPageId)
        {
            PageInRoleNameCollection col = new PageInRoleNameCollection();
            col.Where(PageInRoleName.Columns.PageId, pPageId);
            col.Load();

            return col.ToArray();

        }

        public void AddRolesToPage(Guid pPageId, string[] pRoles)
        {
            if (pRoles.Length < 1)
            {
                return;
            }

            var roleQuery = DALS.Role.Query();
            roleQuery.IN(DALS.Role.Columns.Name, pRoles.Cast<object>().ToArray());
            var roles = new DALS.RoleCollection();
            using (IDataReader reader = roleQuery.ExecuteReader())
            {
                roles.Load(reader);
            }

            if (roles.Count < 1) { return; }

            var pageInRoleDeleteQuery = DALS.PageInRole.Query();
            pageInRoleDeleteQuery.QueryType = QueryType.Delete;
            pageInRoleDeleteQuery.WHERE(DALS.PageInRole.Columns.PageId, pPageId.ToString());
            pageInRoleDeleteQuery.IN(DALS.PageInRole.Columns.RoleId, roles.Select(r => (object)r.RoleId.ToString()).ToArray());
            pageInRoleDeleteQuery.Execute();

            var pageInRoleCol = new DALS.PageInRoleCollection();

            foreach (var role in roles)
            {
                var pageInRole = new PageInRole();
                pageInRole.RoleId = role.RoleId;
                pageInRole.PageId = pPageId;
                pageInRoleCol.Add(pageInRole);
            }
            pageInRoleCol.SaveAll();
        }

        public void RemoveRolesFromPage(Guid pPageId, string[] pRoles)
        {
            if (pRoles.Length < 1)
            {
                return;
            }

            var roleQuery = DALS.Role.Query();
            roleQuery.IN(DALS.Role.Columns.Name, pRoles.Cast<object>().ToArray());
            var roles = new DALS.RoleCollection();
            using (IDataReader reader = roleQuery.ExecuteReader())
            {
                roles.Load(reader);
            }

            if (roles.Count < 1) { return; }

            var pageInRoleDeleteQuery = DALS.PageInRole.Query();
            pageInRoleDeleteQuery.QueryType = QueryType.Delete;
            pageInRoleDeleteQuery.WHERE(DALS.PageInRole.Columns.PageId, pPageId.ToString());
            pageInRoleDeleteQuery.IN(DALS.PageInRole.Columns.RoleId, roles.Select(r => (object)r.RoleId.ToString()).ToArray());
            pageInRoleDeleteQuery.Execute();

        }

        #endregion

        public Guid[] GetVisiblePropertiesForGroups(string[] groupNames)
        {
            var col = new GroupPropertyAssociationCollection();
            col.Where(GroupPropertyAssociation.Columns.GroupName, Comparison.In, groupNames);
            col.Load();

            return col.Select(p => p.PropertyId).ToArray();
        }

        public void AddPropertiesForGroup(Guid[] properties, string group)
        {
            if (group.IsNullOrEmpty())
            {
                return;
            }

            var transaction = new Transaction(GroupPropertyAssociation.Schema.Provider);

            var query = GroupPropertyAssociation.Query();
            query.QueryType = QueryType.Delete;
            query.WHERE(GroupPropertyAssociation.Columns.GroupName, group);
            transaction.Add(query.BuildDeleteCommand());

            foreach (var property in properties)
            {
                var association = new GroupPropertyAssociation();
                association.GroupName = group;
                association.PropertyId = property;
                transaction.Add(association.GetSaveCommand());
            }

            transaction.Execute();
        }

        #endregion

        #region Helper Methods

        private static SecurityLevels GetSecurityLevel(byte level)
        {
            switch (level)
            {
                case 1:
                    return SecurityLevels.Deny;
                case 2:
                    return SecurityLevels.Read;
                case 3:
                    return SecurityLevels.Update;
                case 4:
                    return SecurityLevels.Create;
                case 5:
                    return SecurityLevels.Delete;
                case 6:
                    return SecurityLevels.Grant;
                default:
                    throw new ArgumentException("Unknown security level: " + level.ToString());
            }
        }

        private static byte GetSecurityLevel(SecurityLevels level)
        {
            switch (level)
            {
                case SecurityLevels.Deny:
                    return 1;
                case SecurityLevels.Read:
                    return 2;
                case SecurityLevels.Update:
                    return 3;
                case SecurityLevels.Create:
                    return 4;
                case SecurityLevels.Delete:
                    return 5;
                case SecurityLevels.Grant:
                    return 6;
                case SecurityLevels.Inherited:
                    return 7;
                default:
                    throw new ArgumentException("Unknown security level: " + level.ToString());
            }
        }

        #endregion

        #region Coverters

        private static InheritedPermission FromDALInheritedNodeTypePermission(DALS.InheritedTypePermission permission)
        {
            if (permission.TypeId.HasValue)
            {
                return new InheritedPermission(permission.TypeId.Value,
                    permission.GroupId, GetSecurityLevel(permission.InheritedSecurityLevel),
                    PermissionType.TypePermission, permission.InheritedFromTypeId);
            }

            throw new ArgumentNullException("Cannot create NodeTypePermission for null TypeId.");
        }

        private static Permission FromDALNodeTypePermission(DALS.TypePermission dalPermission)
        {
            return new Permission(dalPermission.TypeId,
                dalPermission.GroupId, GetSecurityLevel(dalPermission.SecurityLevel),
                PermissionType.TypePermission);
        }

        private static Group FromDALGroup(SubSonicDAL.Group arg)
        {
            return new Group(arg.Name, arg.GroupId, arg.ParentGroupId, arg.Path, arg.Depth);
        }

        private static InheritedPermission FromDALInheritedNodePermission(DALS.InheritedNodePermission permission)
        {
            if (permission.NodeId.HasValue)
            {
                return new InheritedPermission(permission.NodeId.Value,
                    permission.GroupId, GetSecurityLevel(permission.InheritedSecurityLevel),
                    PermissionType.NodePermission, permission.InheritedFromNodeId);
            }

            throw new ArgumentNullException("Cannot create NodePermission for null NodeId.");
        }

        private static Permission FromDALNodePermission(DALS.NodePermission dalPermission)
        {
            return new Permission(dalPermission.NodeId,
                dalPermission.GroupId, GetSecurityLevel(dalPermission.SecurityLevel),
                PermissionType.NodePermission);
        }

        private static Approbation FromDALNodeApprobation(NodeApprobation dalApprobation)
        {
            return new Approbation(dalApprobation.NodeId, dalApprobation.Groups);
        }

        private static DALS.NodePermission ToDALNodePermission(Permission permission, bool isNew)
        {
            DALS.NodePermission dalPermission = new DALS.NodePermission()
            {
                GroupId = permission.GroupId,
                NodeId = permission.SecuredObjectId,
                IsNew = isNew,
                IsLoaded = true
            };

            dalPermission.SecurityLevel = GetSecurityLevel(permission.SecurityLevel);

            return dalPermission;
        }

        private static NodeApprobation ToDALNodeApprobation(Approbation approbation, bool isNew)
        {
            var dalApprobation = new NodeApprobation()
            {
                NodeId = approbation.ObjectId,
                IsNew = isNew,
                IsLoaded = true
            };

            dalApprobation.Groups = approbation.Xml;

            return dalApprobation;
        }

        private static DALS.TypePermission ToDALTypePermission(Permission permission, bool isNew)
        {
            DALS.TypePermission dalPermission = new DALS.TypePermission()
            {
                GroupId = permission.GroupId,
                TypeId = permission.SecuredObjectId,
                IsNew = isNew,
                IsLoaded = true
            };

            dalPermission.SecurityLevel = GetSecurityLevel(permission.SecurityLevel);

            return dalPermission;
        }

        #endregion
    }
}
